package org.cfk.delaytasktutorial.service.impl;

import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.cfk.delaytasktutorial.bo.XxlJobBo;
import org.cfk.delaytasktutorial.service.XxlJobService;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.Optional;
import java.util.Set;

@Slf4j
@Service
public class XxlJobServiceImpl implements XxlJobService {

    @Resource
    private ApplicationContext applicationContext;

    @SneakyThrows
    @Override
    public void executeXxlJob(XxlJobBo xxlJobBo) {
        ClassPathScanningCandidateComponentProvider scanner =
                new ClassPathScanningCandidateComponentProvider(true);


        // 扫描指定包下的所有带有 @XxlJob 注解的类
        Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents("org.cfk.delaytasktutorial.job");
        // 遍历类并执行带有 @XxlJob 注解的方法
        for (BeanDefinition beanDefinition : candidateComponents) {

            Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
            Object bean = applicationContext.getBean(clazz);

            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(XxlJob.class)) {
                    XxlJob xxlJobAnnotation = method.getAnnotation(XxlJob.class);
                    if (xxlJobBo.getHandler().equals(xxlJobAnnotation.value())) {
                        Object[] args = new String[]{Optional.ofNullable(xxlJobBo.getParams()).orElse("")};
                        method.invoke(bean, args);
                    }
                }
            }

        }
    }
}
